package mapEditor.svg;

import mapEditor.svg.SVGDOMTree;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;

import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.dom.svg.SVGOMSVGElement;
import org.apache.batik.dom.svg.SVGOMRectElement;
import org.apache.batik.dom.svg.SVGOMRect;

import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
import org.apache.batik.swing.svg.SVGDocumentLoaderAdapter;
import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;
import org.apache.batik.swing.svg.GVTTreeBuilderAdapter;
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.w3c.dom.svg.SVGRect;

// ***************

import org.apache.batik.util.ParsedURL;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.swing.svg.SVGDocumentLoader;
import org.apache.batik.bridge.UserAgentAdapter;
import org.w3c.dom.svg.SVGDocument;

import debug.Debug;


// DOC: file:///C:/Batic/docs/using/swing.html
//
// Note
// If you try this example, do not forget to set your CLASSPATH so that it contains the Batik classes and resources,
// as well as Xerces (lib/xerces_2_5_0.jar) and the XML APIs jars (lib/xml-apis.jar and lib/xml-apis-ext.jar).
//
// + batik-gvt.jar
// + batik-util.jar
// + batik-bridge.jar
// + batik-css.jar
// + batik-xml.jar
// + batik-parser.jar
// + batik-anim.jar
// + batik-util.jar  ???
// + batik-gui-util.jar
// + batik-script.jar
// + batik-ext.jar
// TA ALLE

public class SVGApplication
{
  public static void main(String[] args)
  { // Create a new JFrame.
    JFrame f = new JFrame("Batik");
    SVGApplication app = new SVGApplication(f);

    // Add components to the frame.
    f.getContentPane().add(app.createComponents());

    // Display the frame.
    f.addWindowListener(new WindowAdapter()
    { public void windowClosing(WindowEvent e)
      { System.exit(0); }
    });
    f.setSize(400, 400);
    f.setVisible(true);
  }
    
  // The frame.
  protected JFrame frame;

  // The "Load" button, which displays up a file chooser upon clicking.
  protected JButton button = new JButton("Load...");

  // The status label.
  protected JLabel label = new JLabel();

  // The SVG canvas.
  protected JSVGCanvas svgCanvas = new JSVGCanvas();

  public SVGApplication(JFrame f) { frame = f; }

  public JComponent createComponents()
  { // Create a panel and add the button, status label and the SVG canvas.
    final JPanel panel = new JPanel(new BorderLayout());

    JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
    p.add(button);
    p.add(label);

    panel.add("North", p);
    panel.add("Center", svgCanvas);

    // Set the button action - READ FILE.
    button.addActionListener(new ActionListener()
    { public void actionPerformed(ActionEvent ae)
//    { JFileChooser fc = new JFileChooser(".");
      { JFileChooser fc = new JFileChooser("C:/Documents and Settings/Administrator/Application Data/MapEditor");
        int choice = fc.showOpenDialog(panel);
        if(choice == JFileChooser.APPROVE_OPTION)
        { File f = fc.getSelectedFile();
        try
        { System.out.println("*** URI: "+f.toURL().toString());
        	svgCanvas.setURI(f.toURL().toString());
        }
//          try { testLoading(f.toURL().toString()); }
          catch(IOException ex) { ex.printStackTrace(); }
        }
      }
    });

//    // Set the button action - READ FILE.
//    button.addActionListener(new ActionListener()
//    { public void actionPerformed(ActionEvent ae)
//      { svgCanvas.setDocument(test1());
//      }
//    });

    // Set the JSVGCanvas listeners.
    svgCanvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter()
    { public void documentLoadingStarted(SVGDocumentLoaderEvent e) { label.setText("Document Loading..."); }
      public void documentLoadingCompleted(SVGDocumentLoaderEvent e)
      { label.setText("Document Loaded.");
        SVGOMDocument svgDocument=(SVGOMDocument)e.getSVGDocument();
        printXML(svgDocument,"Created Document (1)");

      }
    });

    svgCanvas.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter()
    { public void gvtBuildStarted(GVTTreeBuilderEvent e) { label.setText("Build Started..."); }
      public void gvtBuildCompleted(GVTTreeBuilderEvent e)
      { label.setText("Build Done.");
        frame.pack();
      }
    });

    svgCanvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter()
    { public void gvtRenderingPrepare(GVTTreeRendererEvent e) { label.setText("Rendering Started..."); }
      public void gvtRenderingCompleted(GVTTreeRendererEvent e) { label.setText(""); }
    });

    return panel;
  }
  
  private static final String DOCTYPE=
	  "-//W3C//DTD SVG 1.1 Tiny//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd";
  
  public void printXML(SVGOMDocument svgDocument,String title)
  {	Debug.println("*** "+title+" ********************************************************************************");  
	try { SVGDOMTree.emitSVG(svgDocument,DOCTYPE,new OutputStreamWriter(System.out)); } catch(Throwable e) { e.printStackTrace(); }
	Debug.println("**********************************************************************************************");   
  }

  
  // ***********************************
  UserAgent userAgent;
  DocumentLoader loader;
  SVGDocumentLoader nextDocumentLoader;
  private void testLoading(String url)
  { 
    /**
    * Loads a SVG document from the given URL.
    * <em>Note: Because the loading is multi-threaded, the current
    * SVG document is not garanteed to be updated after this method
    * returns. The only way to be notified a document has been loaded
    * is to listen to the <tt>SVGDocumentLoaderEvent</tt>s.</em>
    */
	// public void loadSVGDocument(String url)
//	{ String oldURI = null;
//	  //if(svgDocument!=null) { oldURI = svgDocument.getURL(); }
//	  final ParsedURL newURI = new ParsedURL(oldURI, url);
//
//	  stopThenRun(new Runnable()
//	  { public void run()
//	    { String url = newURI.toString();
//	      fragmentIdentifier = newURI.getRef();

	  System.out.println("testLoading:");
	  userAgent=new UserAgentAdapter();
	  loader = new DocumentLoader(userAgent);
	  nextDocumentLoader = new SVGDocumentLoader(url, loader);
	  nextDocumentLoader.setPriority(Thread.MIN_PRIORITY);
	  nextDocumentLoader.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter()
	  { public void documentLoadingStarted(SVGDocumentLoaderEvent e) { System.out.println("Document Loading..."); }
	    public void documentLoadingFailed(SVGDocumentLoaderEvent e) { System.out.println("Document Loading FAILED."); }
	    public void documentLoadingCompleted(SVGDocumentLoaderEvent e)
	    { System.out.println("Document Loaded.");
	      SVGDocument svgDocument=e.getSVGDocument();
	      System.out.println("Document Loaded: svgDocument="+svgDocument);
	  	  try { emitSVG(svgDocument,DTD_URI,System.out); } catch(Throwable ee) { ee.printStackTrace(); }
	    }
	  });
	  nextDocumentLoader.run(); //.start();

	      
//	      Iterator it = svgDocumentLoaderListeners.iterator();
//	      while(it.hasNext())
//	      { nextDocumentLoader.addSVGDocumentLoaderListener((SVGDocumentLoaderListener)it.next()); }
//	      startDocumentLoader();
//	    }
//	  });
//	}  
  }
  
  private Document test1()
  {	
	  SVGDOMImplementation impl = (SVGDOMImplementation)SVGDOMImplementation.getDOMImplementation();
	System.out.println("DOMImplementation: "+impl);
	String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
	System.out.println("SVG_NAMESPACE_URI: "+svgNS);
	SVGOMDocument doc = (SVGOMDocument)impl.createDocument(svgNS, "svg", null);
	System.out.println("Document: "+doc);

//	 Get the root element (the 'svg' element).
	SVGOMSVGElement svgRoot = (SVGOMSVGElement)doc.getDocumentElement();
	System.out.println("svgRoot: "+svgRoot);

//	 Set the width and height attributes on the root 'svg' element.
	svgRoot.setAttributeNS(null, "width", "400");
	svgRoot.setAttributeNS(null, "height", "450");

//	 Create the rectangle.
	SVGOMRectElement rectangle = (SVGOMRectElement)doc.createElementNS(svgNS, "rect");
	rectangle.setAttributeNS(null, "x", "10");
	rectangle.setAttributeNS(null, "y", "20");
	rectangle.setAttributeNS(null, "width", "100");
	rectangle.setAttributeNS(null, "height", "50");
	rectangle.setAttributeNS(null, "fill", "red");
	System.out.println("Rectangle: "+rectangle);
	try { emitSVG(rectangle,System.out); } catch(Throwable e) { e.printStackTrace(); }
	
//  TEST
	

//	 Create the rectangle.
	SVGRect rect = svgRoot.createSVGRect();
	rect.setX(10);
	rect.setY(20);
	rect.setWidth(100);
	rect.setHeight(50);
	System.out.println("Rectangle: "+rect);

//	 Attach the rectangle to the root 'svg' element.
	svgRoot.appendChild(rectangle);
	try { emitSVG(doc,DTD_URI,System.out); } catch(Throwable e) { e.printStackTrace(); }
	return(doc);
  }
  
//  private static final String PROPS_DTD_URI="http://java.sun.com/dtd/properties.dtd";
  private static final String DTD_URI=
  "-//W3C//DTD SVG 1.1 Tiny//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd";

  static void emitSVG(Node node,OutputStream outputStream) throws IOException
  { emitSVG(node,null,outputStream,"UTF-8"); }

  static void emitSVG(Node node,String dtd,OutputStream outputStream) throws IOException
  { emitSVG(node,dtd,outputStream,"UTF-8"); }

//  static void emitSVG(Document document,OutputStream outputStream,String encoding) throws IOException
  static void emitSVG(Node document,String dtd,OutputStream outputStream,String encoding) throws IOException
  { TransformerFactory transformerFactory=TransformerFactory.newInstance();
    Transformer transformer=null;
    try
    { transformer=transformerFactory.newTransformer();
//      transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI);
      if(dtd!=null) transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,dtd);
      else transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");

      transformer.setOutputProperty(OutputKeys.INDENT,"yes");
      transformer.setOutputProperty(OutputKeys.METHOD,"xml");
      transformer.setOutputProperty(OutputKeys.ENCODING,encoding);
    } catch(TransformerConfigurationException tce) { assert(false); }
    DOMSource domSource=new DOMSource(document);
    StreamResult streamResult=new StreamResult(outputStream);
    try { transformer.transform(domSource,streamResult); }
    catch(TransformerException te)
    { IOException ioException=new IOException();
      ioException.initCause(te);
      throw(ioException);
    }
  }


}